//
//  OcrPlatformView.m
//  ocr_plugin
//
//  Created by apple on 2021/9/15.
//

#import "OcrPlatformView.h"
#import "OcrPlatformView_Test.h"

@import AVFoundation;

#import "OcrCameraProperties.h"
#import "OcrCam.h"
#import "OcrThreadSafeEventChannel.h"
#import "OcrThreadSafeFlutterResult.h"
#import "OcrThreadSafeMethodChannel.h"
#import "OcrThreadSafeTextureRegistry.h"
#import "OcrQueueUtils.h"

@interface OcrPlatformView ()

@property(readonly, nonatomic) OcrThreadSafeMethodChannel *threadSafeMethodChannel;

/// 取景框满屏，或接近满屏
@property (nonatomic,assign) BOOL fullArea;

@end

@implementation OcrPlatformView

- (void)dealloc{
    NSLog(@"OcrPlatformView dealloc");
}

- (instancetype)initWithFrame:(CGRect)frame
                       viewId:(int64_t)viewId
                    arguments:(id)args
              binaryMessenger:(NSObject<FlutterBinaryMessenger> *)message{
    
    __weak __typeof__(self) weakSelf = self;
    
    _captureSessionQueue = dispatch_queue_create("io.flutter.ocr.captureSessionQueue", NULL);
    dispatch_queue_set_specific(_captureSessionQueue, OcrCaptureSessionQueueSpecific,
                                (void *)OcrCaptureSessionQueueSpecific, NULL);
    
    //channel
    NSString* name = [NSString stringWithFormat:@"com.jacky.util/ocr_view_%lld",viewId];
    
    
    FlutterMethodChannel *methodChannel = [FlutterMethodChannel methodChannelWithName:name
                                               binaryMessenger:message];
    self.channel = methodChannel;
    
    _threadSafeMethodChannel = [[OcrThreadSafeMethodChannel alloc] initWithMethodChannel:methodChannel];
    
    //处理channel回调
    
    [self.channel setMethodCallHandler:^(FlutterMethodCall * _Nonnull call, FlutterResult  _Nonnull result) {
        if (weakSelf==nil) {
            // 界面销毁，通道未销毁
            return;
        }
        
        dispatch_async(weakSelf.captureSessionQueue, ^{
          OcrThreadSafeFlutterResult *threadSafeResult =
              [[OcrThreadSafeFlutterResult alloc] initWithResult:result];

          [weakSelf handleMethodCallAsync:call result:threadSafeResult];
        });
        
    }];
    
    if (args!=nil&&[args isKindOfClass:[NSDictionary class]]) {
        NSDictionary *dic = (NSDictionary *)args;
        if ([dic.allKeys containsObject:@"iOSFullArea"]) {
            self.fullArea = [dic[@"iOSFullArea"] boolValue];
        }
    }
    
    //显示view
    self.ocrView = [[OcrView alloc]initWithFrame:frame args:args captureSessionQueue:_captureSessionQueue];
    
    //错误信息回调
    [self.ocrView achieveError:^(NSString * _Nonnull code, NSString * _Nonnull message) {
        NSMutableDictionary* dic = [[NSMutableDictionary alloc]init];
        [dic setObject:code forKey:@"code"];
        [dic setObject:message forKey:@"message"];
        [weakSelf sendToFlutter:@"onOcrRectError" dic:dic];
    }];
    //识别结果回调
    [self.ocrView achieveResult:^(NSDictionary * _Nonnull dict) {
        [weakSelf sendToFlutter:@"onOcrRecognize" dic:dict];
    }];
    
    return self;
}

- (nonnull UIView *)view {
    return self.ocrView;
}


///处理flutter发送来的消息
- (void)handleMethodCallAsync:(FlutterMethodCall *)call result:(OcrThreadSafeFlutterResult *)result{
  if ([@"getPlatformVersion" isEqualToString:call.method]) {
      [result sendSuccessWithData:[@"iOS " stringByAppendingString:[[UIDevice currentDevice] systemVersion]]];
  } else if([@"startScan" isEqualToString:call.method]){
      NSDictionary* dic = [call arguments];
      NSString* imgPath = [dic valueForKey:@"ocrImgPath"];
      NSString* headPath = [dic valueForKey:@"ocrHeadPath"];
      [self.ocrView setOcrFilePath:imgPath headPath:headPath];
      [self.ocrView resume];
      
      [result sendSuccess];
  } else if([@"stopScan" isEqualToString:call.method]){
      //对iOS方法无用
      [result sendSuccess];
  } else if([@"toggleFlash" isEqualToString:call.method]){
      //对iOS方法无用
      [result sendSuccess];
  } else if([@"pauseCamera" isEqualToString:call.method]){
      [self.ocrView pause];
      [result sendSuccess];
  } else if([@"resumeCamera" isEqualToString:call.method]){
      [self.ocrView resume];
      [result sendSuccess];
  } else if([@"stopCamera" isEqualToString:call.method]){
      
      [self.ocrView close];
      [result sendSuccess];
      
  } else if([@"setDimensions" isEqualToString:call.method]){
      
      NSDictionary* dic = [call arguments];
      
      CGFloat width = 0;
      CGFloat height = 0;
      
      CGFloat aLeft = 0;
      CGFloat aTop = 0;
      CGFloat aWidth = 0;
      CGFloat aHeight = 0;
      
      CGFloat faceLeft = 0;
      CGFloat faceTop = 0;
      CGFloat faceWidth = 0;
      CGFloat faceHeight = 0;
      
      if ([dic isKindOfClass:NSDictionary.class]) {
          if ([dic.allKeys containsObject:@"width"]) {
              width = [[dic valueForKey:@"width"] doubleValue];
          }
          
          if ([dic.allKeys containsObject:@"height"]) {
              height = [[dic valueForKey:@"height"] doubleValue];
          }
          
          if ([dic.allKeys containsObject:@"areaLeft"]) {
              aLeft = [[dic valueForKey:@"areaLeft"] doubleValue];
          }
          if ([dic.allKeys containsObject:@"areaTop"]) {
              aTop = [[dic valueForKey:@"areaTop"] doubleValue];
          }
          if ([dic.allKeys containsObject:@"areaWidth"]) {
              aWidth = [[dic valueForKey:@"areaWidth"] doubleValue];
          }
          if ([dic.allKeys containsObject:@"areaHeight"]) {
              aHeight = [[dic valueForKey:@"areaHeight"] doubleValue];
          }
          
          if ([dic.allKeys containsObject:@"faceLeft"]) {
              faceLeft = [[dic valueForKey:@"faceLeft"] doubleValue];
          }
          if ([dic.allKeys containsObject:@"faceTop"]) {
              faceTop = [[dic valueForKey:@"faceTop"] doubleValue];
          }
          if ([dic.allKeys containsObject:@"faceWidth"]) {
              faceWidth = [[dic valueForKey:@"faceWidth"] doubleValue];
          }
          if ([dic.allKeys containsObject:@"faceHeight"]) {
              faceHeight = [[dic valueForKey:@"faceHeight"] doubleValue];
          }
      }
      
      CGRect rect,faceRect;
      
      if (self.fullArea) {
          aWidth = width;
          aHeight = height;
      }
      
      if(aWidth <= 0 || aHeight <= 0){
          NSError *error = [NSError errorWithDomain:NSCocoaErrorDomain
                                               code:NSURLErrorUnknown
                                           userInfo:@{
                                             NSLocalizedDescriptionKey : @"areaWidth=0||areaHeight=0"
                                           }];
          [result sendError:error];
          return;
      }
      
      rect = CGRectMake(aLeft, aTop, aWidth, aHeight);
      
      faceRect = CGRectMake(faceLeft, faceTop, faceWidth, faceHeight);
      
      [self.ocrView configAreaFrame:rect faceFrame:faceRect];
      
      [result sendSuccess];
  } else if([@"updateParams" isEqualToString:call.method]){
      NSDictionary* dic = [call arguments];
      if (dic!=nil && [dic isKindOfClass:[NSDictionary class]]){
         [self.ocrView updateParams:dic];
      }
      [result sendSuccess];
  } else if([@"takePhotoLibrary" isEqualToString:call.method]){
      
      [self.ocrView takePhotoLibrary];
      [result sendSuccess];
  } else if([@"takePhotoCamera" isEqualToString:call.method]){
      NSDictionary* dic = [call arguments];
      
      BOOL isWithRect = NO;
      
      if ([dic isKindOfClass:NSDictionary.class]) {
          if ([dic.allKeys containsObject:@"isWithRect"]) {
              isWithRect = [[dic valueForKey:@"isWithRect"] boolValue];
          }
      }
      
      if (isWithRect) {
          [self.ocrView takePhotoCameraWithRect];
      } else {
          [self.ocrView takePhotoCamera];
      }
      
      [result sendSuccess];
  } else if([@"switchCamera" isEqualToString:call.method]){
      
      [self.ocrView switchCamera];
      [result sendSuccess];
  } else {
      [result sendNotImplemented];
  }
    
    
}

///发送给flutter消息，方法名及信息
- (void)sendToFlutter:(NSString*)method dic:(NSDictionary*)dic{
    
    NSLog(@"sendToFlutter method %@, content %@",method,dic);
    @try {
        if(self && self.threadSafeMethodChannel){
            [self.threadSafeMethodChannel invokeMethod:method arguments:dic];
        }
    } @catch (NSException *exception) {
        NSLog(@"ios,ocr view sendToFlutter error, reasion = %@, error = %@",exception.reason,exception);
    }
}

@end
